package workgroup.osaka.DirectLink;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class BluetoothLink extends BroadcastReceiver{

	/*
	 *   マニフェストに以下の記述が必要
	 *   
	 *   Bluetoothによる通信を許可する
	 *  <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
	 *  
	 *   Bluetoothの設定変更を許可する
	 *  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
	 * 
	 */

	//画面のアクティビティ
	DirectLinkMainActivity activity;

	//接続中はtrueにする
	boolean connect = false;
	//送信中はtrueにする
	boolean send = false;

	//相手に送信する画像のＵＲＩ
	Uri SendPicUri = null;

	//Bluetooth通信に必要なクラス
	//自端末情報
	private BluetoothAdapter BtAdapter = null;
	//相手端末情報
	private BluetoothDevice PeerDevice = null;
	//IntentFilterに登録したアクションがレシーバーに通知される
	private IntentFilter IntentFilter;

	//画面層にて表示される名前や状態など
	//自分の端末情報
	private String my_name = "";
	private String my_status = "";
	private String my_mac = "";
	private String my_group = "";

	//接続相手の端末情報
	private String peer_name = "";
	private String peer_status = "";
	private String peer_mac = "";
	private String peer_group = "";

	//このアプリでBluetooth通信に用いるID(一般的に使用されているＩＤと別であれば何でもよい？)
	//他のアプリなどと同じＩＤを使用すると予期していない動作を起こす場合がある
	private UUID Uuid = UUID.fromString("bb87c0d0-afac-11de-8a39-0800200c9a66");

	//サーバーソケット
	private BluetoothSocket ServerSocket = null;
	private  BluetoothServerSocket SvSocket = null;
	//サーバースレッド
	private BluetoothServerThread ServerThread = null;
	//クライアント側のソケット
	private BluetoothSocket ClientSocket = null;
	//クライアントスレッド
	private ClientThread ClientThread = null;

	//接続後はサーバー側もクライアント側もこの変数に代入する
	private BluetoothSocket ConnectSocket;
	//接続時のスレッド
	BondingThread BondingThread = null;

	//コンストラクタ
	BluetoothLink(DirectLinkMainActivity activity){
		this.activity = activity;

		//BluetoothAdapter取得
		BtAdapter = BluetoothAdapter.getDefaultAdapter();
		MyStatus(BtAdapter , "未接続");

		if(!BtAdapter.equals(null)){
			//Bluetooth対応端末の場合の処理
			Log.d("コンストラクタ", "Bluetoothがサポートされてます。");
			//表示
			Toast.makeText(this.activity,
					"Bluetoothがサポートされてます。",
					Toast.LENGTH_SHORT).show();
		}else{
			//Bluetooth非対応端末の場合の処理
			Log.d("コンストラクタ", "Bluetoothがサポートされていません。");
			//表示
			Toast.makeText(this.activity,
					"Bluetoothがサポートされていません、終了します。",
					Toast.LENGTH_SHORT).show();
			this.activity.finish();
		}

		boolean BtEnable = BtAdapter.isEnabled();
		if(BtEnable == true){
			//BluetoothがONだった場合の処理
			Log.d("コンストラクタ", "BluetoothがONになっています");
			//表示
			Toast.makeText(this.activity,
					"BluetoothがONになっています",
					Toast.LENGTH_SHORT).show();

			//自デバイスの検出を有効にする
			Intent discoverableOn = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableOn.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
			this.activity.startActivity(discoverableOn);

		}else{
			//BluetoothがOFFだった場合の処理
			Log.d("コンストラクタ", "BluetoothがOFFになっています");
			//表示
			Toast.makeText(this.activity,
					"BluetoothがOFFになっています",
					Toast.LENGTH_SHORT).show();
			BtAdapter.enable();

			Log.d("コンストラクタ", "BluetoothをONにしました");
			//表示
			Toast.makeText(this.activity,
					"BluetoothをONにしました",
					Toast.LENGTH_SHORT).show();

			//自デバイスの検出を有効にする
			Intent discoverableOn = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableOn.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
			this.activity.startActivity(discoverableOn);

		}

		Log.d("コンストラクタ", "インテントフィルタ作成");
		//インテントフィルターとBroadcastReceiverの登録
		IntentFilter = new IntentFilter();
		
		//////////////////
		IntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
		//////////////////

		//デバイス検出の開始時
		IntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);

		//デバイス検出時
		IntentFilter.addAction(BluetoothDevice.ACTION_FOUND);

		//デバイス名の判明時(新規検出時)
		IntentFilter.addAction(BluetoothDevice.ACTION_NAME_CHANGED);

		//デバイス検出終了時
		IntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

		//ブロードキャストレシーバー登録
		Log.d("コンストラクタ", "ブロードキャストレシーバー登録");
		this.activity.registerReceiver(this, IntentFilter);

		//検索中かどうか
		if(BtAdapter.isDiscovering()){
			Log.d("コンストラクタ", "検索中なので検索をキャンセルします");
			//検索中の場合は検出をキャンセルする
			BtAdapter.cancelDiscovery();
		}

		//デバイスを検索する
		Log.d("コンストラクタ", "デバイスを検索します");
		//一定時間の間検出を行う
		BtAdapter.startDiscovery();

		//サーバースレッドスタート
		ServerThread = new BluetoothServerThread();
		Log.d("コンストラクタ", "サーバースレッドスタート");
		ServerThread.start();


		Log.d("コンストラクタ", "各ボタンの動作設定");
		//各ボタンの動作設定
		SearchButton();
		ConnectButton();
		SendButton();

	}

	//自端末と相手端末の情報を取得する
	String[] getStatus() {
		String[] status = new String[8];
		//自分の端末情報
		status[0] = my_name;
		status[1] = my_status;
		status[2] = my_mac;
		status[3] = my_group;

		//接続相手の端末情報
		status[4] = peer_name;
		status[5] = peer_status;
		status[6] = peer_mac;
		status[7] = peer_group;
		return status;
	}
	
	//アクティビティの画像リストで選んだ画像のＵＲＬをセットする
	void setUri(Uri uri) {
		SendPicUri = uri;
	}

	//画像ファイルを送信する
	void SendPicture(Uri uri){
		Log.d("送信１", "画像送信");
		Log.d("送信１", uri.toString());
		try {
			//相手との通信路の設定
			OutputStream stream = ConnectSocket.getOutputStream();
			Log.d("送信２", "相手との通信路の設定");

			ContentResolver cr = activity.getContentResolver();

			InputStream is = null;
			try {
				//読み込みファイルの準備 ⑦
				is = cr.openInputStream(uri);
				Log.d("送信３", "読み込みファイルの準備");
			} catch (FileNotFoundException e) {
				Log.d("送信エラー１", e.toString());
			}

			//ファイルから読み込み、通信路にデータを流す⑧
			//SendCopyFile(is, stream);
			CopyFile(is, stream , "Send");
			Log.d("送信４", "ファイルから読み込み、通信路にデータを流す");

			//sendをfalseに
			send = false;
			Log.d("送信５", "sendをfalseに");

			//表示
			Toast.makeText(activity,
					"送信完了",
					Toast.LENGTH_SHORT).show();
			Log.d("SendButton", "送信完了");
		} catch (IOException e) {
			Log.e("送信エラー２", "", e);

			//sendをfalseに
			send = false;
			Log.d("送信５", "sendをfalseに");

			//表示
			Toast.makeText(activity,
					"送信完了",
					Toast.LENGTH_SHORT).show();
			Log.d("SendButton", "送信完了");
		}
	}

	//相手端末と切断する
	void Disconnect(){
		if(ConnectSocket != null){
			
			//BondingThreadをnullに
			if(BondingThread != null){
				//インプットストリームを閉じる
				/*
				BondingThread.CloseInStream();
				*/
				BondingThread = null;
			}
			//接続中のソケットをクローズ
			try {
				ConnectSocket.close();
			} catch (IOException e) {
				Log.e("切断エラー", "", e);
			}
			//ConnectSocketをnullに
			if(ConnectSocket != null){
				ConnectSocket = null;
			}
			//ServerThreadをnullに
			if(ServerThread != null){
				ServerThread = null;
			}
			//ServerSocketをnullに
			if(ServerSocket != null){
				ServerSocket = null;
			}
			//ClientThreadをnullに
			if(ClientThread != null){
				ClientThread = null;
			}
			//ClientSocketをnullに
			if(ClientSocket != null){
				ClientSocket = null;
			}
			Log.d("Disconnect", "切断");
		}
	}
	
	//切断ボタンを押したときの動作
	//切断し、検索を行い、サーバーとして待つ
	void Reset(){
		if(connect == true){
			if(BtAdapter == null){
				return;
			}
			
			//相手端末情報をクリア
			Log.d("Reset", "相手端末情報クリア");
			peer_name = "";
			peer_status = "";
			peer_mac = "";
			//役割情報クリア
			my_group = "";
			peer_group = "";
			
			//PeerDeviceをnullに
			PeerDevice = null;
			
			BtAdapter = null;
			//BluetoothAdapter取得
			BtAdapter = BluetoothAdapter.getDefaultAdapter();
			
			//一定時間の間検出を行う
			BtAdapter.startDiscovery();

			
			//自デバイスの検出を有効にする
			//Intent discoverableOn = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			//discoverableOn.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
			//activity.startActivity(discoverableOn);
			

			//切断する
			Disconnect();

			//connectをfalseに
			connect = false;

			
			//切断ボタンを接続ボタンへ
			ConnectButton();
			
			
			//サーバーのスレッドスタート
			Log.d("Reset", "サーバースレッドスタート");
			ServerThread = new BluetoothServerThread();
			ServerThread.start();	
			
			//表示
			Toast.makeText(activity,
					"切断しました",
					Toast.LENGTH_SHORT).show();
			
		}else{
			Log.d("Reset", "接続中ではないので切断しません");
		}
	}

	//検索ボタンの内容を設定する
	void SearchButton(){
		activity.ChangeButton("検索" , new SearchButton() , DirectLinkMainActivity.SEARCH_BUTTON);
		Log.d("SearchButton", "検索ボタン設定");
	}

	//接続ボタンの内容を設定する
	void ConnectButton(){
		activity.ChangeButton("接続" , new ConnectButton() , DirectLinkMainActivity.CONNECT_BUTTON);
		Log.d("ConnectButton", "接続ボタン設定");
	}

	//切断ボタンの内容を設定する
	void DisconnectButton(){
		activity.ChangeButton("切断" , new DisconnectButton() , DirectLinkMainActivity.CONNECT_BUTTON);
		Log.d("DisconnectButton", "切断ボタン設定");
	}

	//送信ボタンの内容を設定する
	void SendButton(){
		activity.ChangeButton("送信" , new SendButton() , DirectLinkMainActivity.SEND_BUTTON);
		Log.d("SendButton", "送信ボタン設定");
	}

	//検索ボタンを押した時の内容
	class SearchButton implements OnClickListener{

		// ボタンがクリックされた時
		@Override
		public void onClick(View v) {
			// クリックされた時の処理を記述
			Log.d("SearchButton", "検索ボタンクリック");

			//接続していなかったら
			if(connect == true){
				Log.d("SearchButton", "接続中は検索できません");
				//表示
				Toast.makeText(activity,
						"接続中は検索できません",
						Toast.LENGTH_SHORT).show();
			}else{
				//相手端末情報をクリア
				Log.d("SearchButton", "相手端末情報クリア");
				PeerDevice = null;
				peer_name = "";
				peer_status = "";
				peer_mac = "";

				//一定時間の間検出を行う
				BtAdapter.startDiscovery();
			}
		}
	}

	//接続ボタンを押した時の内容
	class ConnectButton implements OnClickListener{
		// ボタンがクリックされた時
		@Override
		public void onClick(View v) {
			// クリックされた時の処理を記述
			Log.d("ConnectButton", "接続ボタンクリック");

			//接続相手がいれば接続
			if(PeerDevice != null){
				Log.d("ConnectButton", "接続");

				//クライアントのスレッドをスタートさせる
				ClientThread = new ClientThread();
				Log.d("ConnectButton", "クライアントスレッドスタート");
				ClientThread.start();

			}
			//いなければトースト表示
			else{
				Log.d("ConnectButton", "接続相手無し");
				//表示
				Toast.makeText(activity,
						"接続相手無し",
						Toast.LENGTH_SHORT).show();
			}

		}
	}

	//切断ボタンを押した時の内容
	class DisconnectButton implements OnClickListener{
		// ボタンがクリックされた時
		@Override
		public void onClick(View v) {
			// クリックされた時の処理を記述
			Log.d("DisconnectButton", "切断ボタンクリック");
			//切断処理
			Reset();
		}
	}

	//送信ボタンを押した時の内容
	class SendButton implements OnClickListener{
		// ボタンがクリックされた時
		@Override
		public void onClick(View v) {
			// クリックされた時の処理を記述
			Log.d("SendButton", "送信ボタンクリック");
			if(connect == true){
				if(SendPicUri != null){
					if(send == false){
						//送信確認ダイアログを出す
						SendPicDialog();
					}else{
						//表示
						Toast.makeText(activity,
								"データ送信中なので送信できません",
								Toast.LENGTH_SHORT).show();
						Log.d("SendButton", "データ送信中なので送信できません");
					}
				}else{
					//表示
					Toast.makeText(activity,
							"画像が選ばれていません",
							Toast.LENGTH_SHORT).show();
					Log.d("SendButton", "画像が選ばれていません");
				}
			}else{
				//表示
				Toast.makeText(activity,
						"送信相手無し",
						Toast.LENGTH_SHORT).show();
				Log.d("SendButton", "送信相手無し");
			}
		}
	}
	
	//送信確認ダイアログ表示
	private void SendPicDialog(){
		AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
		dialog.setTitle("確認");
		dialog.setMessage("送信しますか？");
		dialog.setPositiveButton("送信",new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				//sendをtrueに
				send = true;

				//画像送信処理
				Log.d("SendButton", "送信処理");

				//画像を送信する
				SendPicture(SendPicUri);
				//表示
				Toast.makeText(activity,
						"画像を送信します",
						Toast.LENGTH_SHORT).show();
				Log.d("SendButton", "画像を送信します");
			}
		});
		dialog.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				//表示
				Toast.makeText(activity,
						"送信をキャンセルします",
						Toast.LENGTH_SHORT).show();
				Log.d("SendButton", "送信をキャンセルします");
			}
		});
		dialog.show();
	}

	//インテントフィルターに登録したアクションの通知をここで受けて処理を行う
	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		BluetoothDevice foundDevice;

		if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
			
			//接続中になったら自端末状態設定
			if(intent.getExtras().getInt(BluetoothDevice.EXTRA_BOND_STATE) == BluetoothDevice.BOND_BONDING ){
				my_status = "接続中";
			}
		}
		else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
			//デバイス検索開始
			Log.d("onReceive", "デバイス検索を開始します");
			MyStatus(BtAdapter , "未接続");
		}else if(BluetoothDevice.ACTION_FOUND.equals(action)){
			//デバイスが検出された
			Log.d("onReceive", "デバイスを検出しました");
			foundDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
			if((foundDevice.getName()) != null){
				if(PeerDevice != null){
					//発見した相手端末が接続履歴ありの場合PeerDeviceを入れ替える
					if(foundDevice.getBondState() == BluetoothDevice.BOND_BONDED ){
						
						//発見した相手端末情報取得
						PeerDevice = foundDevice;
						//相手端末情報を画面に設定する
						PeerStatus(PeerDevice);
						//表示
						Toast.makeText(activity,
								"デバイスを検出しました",
								Toast.LENGTH_SHORT).show();
					}else{
						//何もしない
					}
				}else{
					
					//発見した相手端末情報取得
					PeerDevice = foundDevice;
					//相手端末情報を画面に設定する
					PeerStatus(PeerDevice);
					//表示
					Toast.makeText(activity,
							"デバイスを検出しました",
							Toast.LENGTH_SHORT).show();
				}
			}else{
				//何もしない
			}
		}else if(BluetoothDevice.ACTION_NAME_CHANGED.equals(action)){
			//名前が検出された
			Log.d("onReceive", "デバイス名の判明時(新規検出時)");

			foundDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
			if((foundDevice.getName()) != null){
				if(PeerDevice != null){
					//発見した相手端末が接続履歴ありの場合PeerDeviceを入れ替える
					if(foundDevice.getBondState() == BluetoothDevice.BOND_BONDED){
						
						//発見した相手端末情報取得
						PeerDevice = foundDevice;
						//相手端末情報を画面に設定する
						PeerStatus(PeerDevice);
						//表示
						Toast.makeText(activity,
								"デバイスを検出しました",
								Toast.LENGTH_SHORT).show();
					}else{
						//何もしない
					}
				}else{
					//発見した相手端末情報取得
					PeerDevice = foundDevice;
					//相手端末情報を画面に設定する
					PeerStatus(PeerDevice);
					//表示
					Toast.makeText(activity,
							"デバイスを検出しました",
							Toast.LENGTH_SHORT).show();
				}
			}else{
				//何もしない
			}
		}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
			//デバイスの検索終了
			Log.d("onReceive", "デバイスの検索終了");
			MyStatus(BtAdapter , "未接続");
		}

	}

	//自分端末の情報を更新する
	void MyStatus(BluetoothAdapter mydevice , String state){
		Log.d("MyStatus", "自分端末情報を更新する");
		if(mydevice != null){
			Log.d("MyStatus", "mydevice は null ではありません");
			//自端末情報取得
			my_name = mydevice.getName();
			my_mac = mydevice.getAddress();
			//my_status = state;
		}
	}

	//相手端末の情報を更新する
	void PeerStatus(BluetoothDevice peerdevice){
		Log.d("PeerStatus", "相手端末情報を更新する");
		if(peerdevice != null){
			Log.d("PeerStatus", "peerdevice は null ではありません");
			//相手端末情報取得
			peer_name = peerdevice.getName();
			peer_mac = peerdevice.getAddress();
			peer_status = getBondStatus(peerdevice.getBondState());
			Log.d("PeerStatus", "" + peerdevice.getBondState());
		}
	}

	//相手端末との接続状態を取得する
	String getBondStatus(int state) {
		String strState;

		switch (state) {
		case BluetoothDevice.BOND_BONDING:
			strState = "接続中";
			break;
		case BluetoothDevice.BOND_BONDED:
			strState = "接続履歴あり";
			break;
		case BluetoothDevice.BOND_NONE:
			strState = "接続履歴なし";
			break;
		default :
			strState = "不明";
		}
		return strState;
	}


	//アプリ再開時の処理(onResume)
	void Resume() {
		Log.d("Resume", "アプリ再開");
		//ブロードキャストレシーバの登録
		this.activity.registerReceiver(this,IntentFilter);
		
		
	}
	
	//アプリ再開時の処理(onStart)
	void Start(){
		Log.d("Start", "アプリ再開");
		//BluetoothAdapter取得
		BtAdapter = BluetoothAdapter.getDefaultAdapter();
		//接続していなかったら
		if(connect == false){
			//サーバースレッドスタート
			ServerThread = new BluetoothServerThread();
			Log.d("Resume", "サーバースレッドスタート");
			ServerThread.start();
		}
	}
	
	//アプリ中断時の処理(onStop)
	void Stop(){
		Log.d("Stop", "アプリ中断");
		//接続していなかったら
		if(connect == false){
			
			if(SvSocket != null){
				try {
					SvSocket.close();
				} catch (IOException e) {}
			}
			
			if(ServerSocket != null){
				ServerSocket = null;
			}
		}
	}

	//アプリ終了時の処理
	void Destroy() {
		Log.d("Destroy", "アプリ終了");
		
		//終了する
		Disconnect();
		
		//レシーバーを解除する
		UnregisterReceiver();

		//各インスタンスをnullに（メモリ圧迫対策のため？）
		//画面のアクティビティ
		//activity = null;

		//相手に送信する画像のＵＲＩ
		SendPicUri = null;

		//自端末情報
		BtAdapter = null;
		//相手端末情報
		PeerDevice = null;
		//IntentFilterに登録したアクションがレシーバーに通知される
		IntentFilter = null;

		//このアプリでBluetooth通信に用いるID(一般的に使用されているＩＤと別であれば何でもよい？)
		//他のアプリなどと同じＩＤを使用すると予期していない動作を起こす場合がある
		Uuid = null;

		//サーバーソケット
		ServerSocket = null;
		SvSocket = null;
		//サーバースレッド
		ServerThread = null;
		//クライアント側のソケット
		ClientSocket = null;

		//接続後はサーバー側もクライアント側もこの変数に代入する
		ConnectSocket = null;
		//接続時のスレッド
		BondingThread = null;
	}

	//レシストレシーバーを解除する
	void UnregisterReceiver(){
		Log.d("UnregisterReceiver", "レジストレシーバー解除");
		activity.unregisterReceiver(this);
	}

	//Bluetoothのサーバーのソケットをスレッド処理で開いて
	//クライアントからの接続を待つ、またはこちらから接続するまで待つ
	class BluetoothServerThread extends Thread{

		@Override   
		public void run() {
			try {
				
				if(BtAdapter == null){
					return;
				}else{
					Log.d("BluetoothServerThread", "BtAdapterはnullではありません");
				}
				//自端末情報設定
				my_status = "未接続";
				
				Log.d("BluetoothServerThread", "SvSocket取得");
				SvSocket = BtAdapter.listenUsingRfcommWithServiceRecord(activity.getPackageName(), Uuid);
				//SvSocket = BtAdapter.listenUsingInsecureRfcommWithServiceRecord(activity.getPackageName(), Uuid);
				Log.d("BluetoothServerThread", "サーバーとして待機します");
				ServerSocket = SvSocket.accept();

				//接続ボタンを切断ボタンへ
				activity.runOnUiThread(new Runnable() {
					public void run() {
						Log.d("ConnectThread", "接続ボタンを切断ボタンへ");
						DisconnectButton();
					}
				});
				
				//接続状態
				connect = true;
				
				//サーバースレッドをnullに
				ServerThread = null;

				//どちらがオーナーか表示する
				Log.d("BluetoothServerTask", "自分がサーバー");
				my_group = "サーバー";
				peer_group = "クライアント";

				//端末情報更新
				MyStatus(BtAdapter , "接続中");
				//PeerStatus(PeerDevice);
				PeerStatus(ServerSocket.getRemoteDevice());

				//他の端末からの接続要求を受けないようにする
				Log.d("BluetoothServerTask", "サーバーソケットクローズ");
				if(SvSocket != null){
					SvSocket.close();
				}else{
					Log.d("BluetoothServerTask", "サーバーソケットはnullです");
				}
				
				//接続時のスレッドをスタートさせる
				BondingThread = new BondingThread(ServerSocket);
				Log.d("BluetoothServerThread", "接続中スレッドスタート");
				BondingThread.start();

			} catch (IOException e) {
				Log.e("受信エラー", e.getMessage());
			}
			return;
		}
	}

	//クライアントが接続ボタンを押した時の処理
	class ClientThread extends Thread{

		@Override   
		public void run() {
			try {

				//相手のサーバーソケットへ接続するための準備
				ClientSocket = PeerDevice.createRfcommSocketToServiceRecord(Uuid);
				//ClientSocket = PeerDevice.createInsecureRfcommSocketToServiceRecord(Uuid);
				//接続するために検索を止める
				BtAdapter.cancelDiscovery();
				//接続する
				ClientSocket.connect();

				//接続ボタンを切断ボタンへ
				activity.runOnUiThread(new Runnable() {
					public void run() {
						Log.d("ConnectThread", "接続ボタンを切断ボタンへ");
						DisconnectButton();
					}
				});
				
				//接続状態
				connect = true;
				
				//クライアントスレッドをnullに
				ClientThread = null;

				//どちらがオーナーか表示する
				Log.d("ConnectButton", "自分がクライアント");
				my_group = "クライアント";
				peer_group = "サーバー";

				//端末情報更新
				MyStatus(BtAdapter , "接続中");
				//PeerStatus(PeerDevice);
				PeerStatus(ClientSocket.getRemoteDevice());

				//ソケットを閉じる
				Log.d("ConnectButton", "サーバー用に開いていたソケットを閉じる");
				if(SvSocket != null){
					SvSocket.close();
				}else{
					Log.d("BluetoothServerTask", "サーバーソケットはnullです");
				}

				Log.d("ConnectButton", "接続中スレッド作成");
				//接続時のスレッドをスタートさせる
				BondingThread = new BondingThread(ClientSocket);
				Log.d("ConnectButton", "接続中スレッドスタート");
				BondingThread.start();

			} catch (IOException e) {
				Log.e("接続エラー", e.getMessage());
				//表示
				activity.runOnUiThread(new Runnable() {
					public void run() {
						Log.d("ConnectThread", "接続失敗");
						Toast.makeText(activity,
								"接続に失敗しました",
								Toast.LENGTH_SHORT).show();
					}
				});
			}
			return;
		}
	}

	//接続したらオーナーもクライアントもこのスレッドを使用
	class BondingThread extends Thread{

		InputStream InStream;

		byte[] buffer = new byte[1024];
		int bytes;

		//コンストラクタ
		BondingThread(BluetoothSocket socket){
			Log.d("BondingThread", "コンストラクタ");
			ConnectSocket = socket; 
			InputStream In = null;

			try {
				In = ConnectSocket.getInputStream();
			} catch (IOException e) {
				Log.e("BondingThread", "ストリームが取得できませんでした：", e);
			}

			Log.d("接続中１", "受信用の通信路と送信用の通信路を準備");
			//インプットストリームを取得
			InStream = In;

		}

		@Override   
		public void run() {
			
			while (true) {
				try {
					bytes = InStream.read(buffer);
				} catch (IOException e) {
					Log.e("受信エラー１", "" + e);
					
					//切断されたら切断処理
					activity.runOnUiThread(new Runnable() {
						public void run() {
							Log.d("ConnectThread", "切断処理");
							Reset();
						}
					});
					
					return;

				}

				if(bytes!=0){
					try {
						//出力ファイルの絶対PATHを設定
						final File f = new File(Environment.getExternalStorageDirectory() + "/"
								+ activity.getApplication().getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
								+ ".jpg");
						Log.d("受信２", "ファイル作成："+ f.getName());
						Log.d("受信３", "ファイル作成："+ f.getPath());

						//出力ファイルの作成準備
						File dirs = new File(f.getParent());
						Log.d("受信４", "ファイル作成");

						//ディレクトリが無ければ作成？
						if (!dirs.exists())
							dirs.mkdirs();
						Log.d("受信５", "ディレクトリ作成");

						//出力ファイルを作成？⑨
						f.createNewFile();
						Log.d("受信６", "server: copying files " + f.toString());

						//アウトプットストリーム
						OutputStream  OutStream  = new FileOutputStream(f);
						//初めに読んだデータを書き込む
						OutStream.write(buffer);

						//受信して出力ファイルに書き出す⑩
						//boolean copyfile = AcceptCopyFile(InStream, OutStream);
						boolean copyfile = CopyFile(InStream, OutStream , "Accept");

						if(copyfile == true){
							Log.d("受信７", "受信して出力ファイルに書き出す");
							//使用したファイルの絶対PATHを返す
							String result = f.getAbsolutePath();

							if (result != null) {
								Log.d("受信８", "File copied - " + result);
								//受信した画像を表示
								activity.DisplayPicture(result);
							}else{
								Log.d("受信９", "result = " + result);
							}
						}else{
							Log.e("受信エラー２", "正しくファイルを受信できませんでした");
						}

						bytes = 0;
					} catch (IOException error) {
						Log.e("受信エラー３", "接続が切れました", error);
						// Start the service over to restart listening mode
						return;
					}
				}
			}
		}
		
		//インプットストリームを閉じる
		void CloseInStream(){
			try {
				//相手との通信路の設定
				OutputStream stream = ConnectSocket.getOutputStream();
				stream.close();
				stream = null;
				InStream.close();
				InStream = null;
			} catch (IOException e) {}
		}
	}
	
	private synchronized boolean CopyFile(InputStream inputStream , OutputStream out , String str){
		if(str == "Send"){
			byte buf[] = new byte[1024];
			int len;
			//inputStreamから画像ファイルを読み込む
			try {
				//ストリームにデータがある限り読み込んでwriteする
				while ((len = inputStream.read(buf)) != -1) {
					out.write(buf, 0, len);
					Log.d("SendCopyFile", "書き込み中");
				}
				Log.d("SendCopyFile", "書き込み終了");
				//書き終わったらしばらく待機
				try {
					Thread.sleep(500);
				}
				catch (InterruptedException e) {
					//
				}
				//inputStreamを閉じる
				inputStream.close();
			} catch (IOException e) {
				Log.e("書き込み", e.toString());
				return false;
			}
		}else if(str == "Accept"){
			byte buf[] = new byte[1024];
			int len;
			int cnt = 0;

			//inputStreamからデータを読み込む
			try {
				while(true){
					//ストリームに１バイト以上のデータがあれば
					if(inputStream.available() > 0){
						//Log.d("copyFile","" + inputStream.available());

						//ストリームから読み込む
						len = inputStream.read(buf);

						//データの終端ならばbreak
						if(len == -1)break;
						//Log.d("copyFile",""+ len);

						//指定したファイルに書き込みする
						out.write(buf, 0, len);
						//Log.d("copyFile", "書き込み中");

					}
					//ストリームが０バイトならば
					if(inputStream.available() == 0){
						cnt = 0;
						while(true){
							//ストリームが１バイト以上になればbreak
							if(inputStream.available() > 0)break;
							//20msec待機
							try {
								Thread.sleep(20);
							}
							catch (InterruptedException e) {
								//
							}
							// 20msec × １０回ストリームにデータが無ければ
							//そこでデータの終端とみなし、returnする
							cnt++;
							if(cnt >= 10){
								//アウトプットストリームをクローズする
								out.close();
								return true;
							}
						}
					}
				}
				//アウトプットストリームをクローズする
				out.close();
				//inputStream.close();
				Log.d("SendCopyFile", "書き込み終了");
			} catch (IOException e) {
				Log.e("書き込み", e.toString());
				return false;
			}
		}
		return true;
	}

	/*
	//ファイル送信の際に使用
	private boolean SendCopyFile(InputStream inputStream, OutputStream out) {

		byte buf[] = new byte[1024];
		int len;
		//inputStreamから画像ファイルを読み込む
		try {
			//ストリームにデータがある限り読み込んでwriteする
			while ((len = inputStream.read(buf)) != -1) {
				out.write(buf, 0, len);
				Log.d("SendCopyFile", "書き込み中");
			}
			Log.d("SendCopyFile", "書き込み終了");
			//書き終わったらしばらく待機
			try {
				Thread.sleep(500);
			}
			catch (InterruptedException e) {
				//
			}
			//inputStreamを閉じる
			inputStream.close();
		} catch (IOException e) {
			Log.e("書き込み", e.toString());
			return false;
		}
		return true;
	}

	//ファイル受信の際に使用
	private boolean AcceptCopyFile(InputStream inputStream, OutputStream out) {

		byte buf[] = new byte[1024];
		int len;
		int cnt = 0;

		//inputStreamからデータを読み込む
		try {
			while(true){
				//ストリームに１バイト以上のデータがあれば
				if(inputStream.available() > 0){
					//Log.d("copyFile","" + inputStream.available());

					//ストリームから読み込む
					len = inputStream.read(buf);

					//データの終端ならばbreak
					if(len == -1)break;
					//Log.d("copyFile",""+ len);

					//指定したファイルに書き込みする
					out.write(buf, 0, len);
					//Log.d("copyFile", "書き込み中");

				}
				//ストリームが０バイトならば
				if(inputStream.available() == 0){
					cnt = 0;
					while(true){
						//ストリームが１バイト以上になればbreak
						if(inputStream.available() > 0)break;
						//20msec待機
						try {
							Thread.sleep(20);
						}
						catch (InterruptedException e) {
							//
						}
						// 20msec × １０回ストリームにデータが無ければ
						//そこでデータの終端とみなし、returnする
						cnt++;
						if(cnt >= 10){
							//アウトプットストリームをクローズする
							out.close();
							return true;
						}
					}
				}
			}
			//アウトプットストリームをクローズする
			out.close();
			//inputStream.close();
			Log.d("SendCopyFile", "書き込み終了");
		} catch (IOException e) {
			Log.e("書き込み", e.toString());
			return false;
		}
		return true;
	}
	*/
	

}
